---
title: "Configuration"
metaTitle: "Build System Configuration"
description: "Details about the configuration of the ReScript build system (rescript.json)"
canonical: "/docs/manual/build-configuration"
section: "Build System"
order: 2
---

# Configuration

`rescript.json` is the single, mandatory build meta file needed for `rescript`.

**The complete configuration schema is [here](./build-configuration-schema.mdx)**. We'll _non-exhaustively_ highlight the important parts in prose below.

## name, namespace

`name` is the name of the library, used as its "namespace". You can activate namespacing through `"namespace": true` in your `rescript.json`. Namespacing is almost **mandatory**; we haven't turned it on by default yet to preserve backward-compatibility.

**Explanation**: by default, your files, once used as a third-party dependency, are available globally to the consumer. E.g. if you have a `Util.res` and the consumer also has a file of the same name, they will clash. Turning on `namespace` avoids this by wrapping all your own project's files into an extra module layer; instead of a global `Util` module, the consumer will see you as `MyProject.Util`. **The namespacing affects your consumers, not yourself**.

Aka, in ReScript, "namespace" is just a fancy term for an auto-generated module that wraps all your project's files (efficiently and correctly, of course!) for third-party consumption.

We don't do folder-level namespacing for your own project; all your own file names must be unique. This is a constraint that enables several features such as fast search and easier project reorganization.

**Note**: the `rescript.json` `name` should be the same as the `package.json` `name`, to avoid confusing corner-cases. However, this means that you can't use a camelCased names such as `MyProject`, since `package.json` and npm forbid you to do so (some file systems are case-insensitive). To have the namespace/module as `MyProject`, write `"name": "my-project"`. ReScript will turn that into the camelCased name correctly.

**Note on custom namespacing**: if for some reason, you need a namespace that is different from what your `name` will produce, you can directly send a string to the `namespace` option. For example, if your package is a binding named `bs-some-thing`, you can use `"namespace": "some-thing"` to get `SomeThing` namespace instead of `BsSomeThing`.

## sources

Your source files need to be specified explicitly (we don't want to accidentally drill down into some unrelated directories). Examples:

```json
{
  "sources": ["src", "examples"]
}
```

```json
{
  "sources": {
    "dir": "src",
    "subdirs": ["page"]
  }
}
```

```json
{
  "sources": [
    "examples",
    {
      "dir": "src",
      "subdirs": true // recursively builds every subdirectory
    }
  ]
}
```

You can mark your directories as dev-only (for e.g. tests). These won't be built and exposed to third-parties, or even to other "dev" directories in the same project:

```json
{
  "sources": {
    "dir": "test",
    "type": "dev"
  }
}
```

You can also explicitly allow which modules can be seen from outside. This feature is especially useful for library authors who want to have a single entry point for their users.  
Here, the file `src/MyMainModule.res` is exposed to outside consumers, while all other files are private.

```json
{
  "sources": {
    "dir": "src",
    "public": ["MyMainModule"]
  }
}
```

## bs-dependencies, bs-dev-dependencies

List of ReScript dependencies. Just like `package.json`'s dependencies, they'll be searched in `node_modules`.

Note that only sources marked with `"type":"dev"` will be able to resolve modules from `bs-dev-dependencies`.

## external-stdlib

**Since 9.0**: This setting allows depending on an externally built stdlib package (instead of a locally built stdlib runtime). Useful for shipping packages that are only consumed in JS or TS without any dependencies to the ReScript development toolchain.

More details can be found on our [external stdlib](./build-external-stdlib.mdx) page.

## js-post-build

Hook that's invoked every time a file is recompiled. Good for JS build system interop, but please use it **sparingly**. Calling your custom command for every recompiled file slows down your build and worsens the building experience for even third-party users of your lib.

Example:

```json
{
  "js-post-build": {
    "cmd": "/path/to/node ../../postProcessTheFile.js"
  }
}
```

Note that the path resolution for the command (`node` in this case) is done so:

- `/myCommand` is resolved into `/myCommand`
- `package/myCommand` is resolved into `node_modules/package/myCommand`
- `./myCommand` is resolved into `myProjectRoot/myCommand`
- `myCommand` is just called as `myCommand`, aka a globally available executable. But note that ReScript doesn't read into your shell's environment, so if you put e.g. `node`, it won't find it unless you specify an absolute path. Alternatively, add `#!/usr/local/bin/node` to the top of your script to directly call it without prepending `node`.

The command itself is called from inside `lib/bs`.

## jsx

Controls how the compiler emits JSX and which runtime (if any) it delegates to. A minimal configuration looks like this:

```json
{
  "jsx": {
    "version": 4
  }
}
```

- `version`: JSX transform version. `4` enables the React 17+ transform and is the current and only supported option in v12.
- `module`: Override the target module that receives JSX calls. Useful for [generic JSX transforms](./jsx.mdx#generic-jsx-transform-jsx-beyond-react-experimental); omit it when using the built-in React runtime.
- `preserve`: When `true`, the compiler re-emits JSX syntax in the generated JavaScript so bundlers or other tooling can take over the transform later. The regenerated JSX might differ slightly from the original source but stays semantically equivalent. See [Preserve mode](./jsx.mdx#preserve-mode) for details.

All fields are optional; unspecified fields fall back to the defaults mentioned above. Combine them as needed for your project's JSX runtime.

## package-specs

Output to either CommonJS (the default) or JavaScript module. Example:

```json
{
  "package-specs": {
    "module": "commonjs",
    "in-source": true
  }
}
```

- `"module": "commonjs"` generates output as CommonJS format.
- `"module": "esmodule"` generates output as JavaScript module format. Will be default value in next major.
- `"in-source": true` generates output alongside source files. If you omit it, it'll generate the artifacts into `lib/js`. The output directory is not configurable otherwise.

This configuration only applies to you, when you develop the project. When the project is used as a third-party library, the consumer's own `rescript.json` `package-specs` overrides the configuration here, logically.

## suffix

**Since 11.0**: The suffix can now be freely chosen. However, we still suggest you stick to the convention and use
one of the following:

- `".js`
- `".mjs"`
- `".cjs"`
- `".res.js"`
- `".res.mjs"`
- `".res.cjs"`

### Design Decisions

Generating JS files with the `.res.js` suffix means that, on the JS side, you can do `const myReScriptFile = require('./TheFile.res.js')`. The benefits:

- It's immediately clear that we're dealing with a generated JS file here.
- It avoids clashes with a potential `TheFile.js` file in the same folder.
- It avoids the need of using a build system loader for ReScript files. This + in-source build means integrating a ReScript project into your pure JS codebase **basically doesn't touch anything in your build pipeline at all**.

## warnings

Selectively turn on/off certain warnings and/or turn them into hard errors. Example:

```json
{
  "warnings": {
    "number": "-44-102",
    "error": "+5"
  }
}
```

Turn off warning `44` and `102` (polymorphic comparison). Turn warning `5` (partial application whose result has function type and is ignored) into a hard error.

The warning numbers are shown in the build output when they're triggered. See [Warning Numbers](./warning-numbers.mdx) for the complete list.

## bsc-flags

Extra flags to pass to the compiler. For advanced usages.

- `-open ABC` opens the module `ABC` for each file in the project. `ABC` can either be a dependency, namespaced project or local module of the current project.

## gentypeconfig

To enable genType, set `"gentypeconfig"` at top level in the project's `rescript.json`.

```json
{
  "gentypeconfig": {
    "module": "esmodule",
    "moduleResolution": "node",
    "generatedFileExtension": ".gen.tsx",
    "debug": {
      "all": false,
      "basic": false
    }
  }
}
```

`generatedFileExtension`: File extension used for genType generated files (defaults to `".gen.tsx"`)

`module`: Module format used for the generated `*.gen.tsx` files (supports `"esmodule"` and `"commonjs"`)

`moduleResolution`: Module resolution strategy used in genType outputs. This may be required for compatibility with TypeScript projects. Specify the value as the same in `tsconfig.json`.

- `"node"`(default): Drop extensions in import paths.
- `"node16"`: Use TS output's extension. This provides compatibility with projects using `"moduleResolution": "node16"` and ES Modules.
- `"bundler"`: Use TS input's extension. This provides compatibility with projects using `"moduleResolution": "bundler"` and ES Modules. This also requires TS v5.0+ and `compilerOptions.allowImportingTsExtensions` to `true`

`debug`: Enable debug logs.

## Environment Variables

We heavily disrecommend the usage of environment variables, but for certain cases, they're justified.

### Error Output Coloring: `FORCE_COLOR`

This is mostly for other programmatic usage of `rescript` where outputting colors is not desired.

When `FORCE_COLOR` is set to `1`: `rescript` produces color.
When `FORCE_COLOR` is set to `0`: `rescript` doesn't produce color.
When `FORCE_COLOR` is not set: `rescript` might or might not produce color, depending on a smart detection of where it's outputted.

> Note that the underlying compiler will always be passed `-color always`. See more details in [this issue](https://github.com/rescript-lang/rescript-compiler/issues/2984#issuecomment-410669163).
